package com.mrd.gtimpframe.action;

import com.mrd.base.Jqgrid;
import com.mrd.exception.QueryException;
import com.mrd.framework.config.web.json.Result;
import com.mrd.framework.security.config.SecurityConstants;
import com.mrd.framework.ui.filter.SearchRule;
import com.mrd.framework.ui.filter.SearchRuleOption;
import com.mrd.framework.utils.HttpUtils;
import com.mrd.gtimp.business.entity.DeclaCheckContent;
import com.mrd.gtimp.business.entity.DeclaCheckResult;
import com.mrd.gtimp.business.entity.DeclaCheckTracking;
import com.mrd.gtimp.business.entity.Declaration;
import com.mrd.gtimp.business.entity.DeclarationFreeDetail;
import com.mrd.gtimp.business.entity.Dictionary;
import com.mrd.gtimp.business.service.DeclarationBiz;
import com.mrd.gtimp.business.service.DeclarationFreeBiz;
import com.mrd.gtimp.business.service.DeclarationFreeDetailBiz;
import com.mrd.gtimp.business.service.DictionaryBiz;
import com.mrd.gtimp.business.service.UserServiceBiz;
import com.mrd.gtimpframe.entity.Company;
import com.mrd.gtimpframe.entity.RejectRecord;
import com.mrd.gtimpframe.entity.User;
import com.mrd.gtimpframe.repository.FundAccountMapper;
import com.mrd.gtimpframe.repository.UserServiceMapper;
import com.mrd.gtimpframe.service.RejectRecordService;
import com.mrd.gtimpframe.service.RejectService;
import com.mrd.util.LoginUtil;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

/**
 * Created by lenovo on 2017/7/7.
 * Created by dark on 17/7/20.
 */
@Controller
@RequestMapping("/wx")
public class UserServiceAction {

    @Resource
    private UserServiceMapper userServiceMapper;
    @Resource
    private FundAccountMapper fundAccountMapper;
    @Resource
    private UserServiceBiz userServiceBiz;
    @Resource
    private DeclarationBiz declarationBiz;
    @Resource
    private DictionaryBiz dictionaryBiz;
    @Resource
    private RejectService rejectService;
    @Resource
    private RejectRecordService rejectRecordService;
    @Resource
    private DeclarationFreeDetailBiz declarationFreeDetailBiz;
    @Resource
    private DeclarationFreeBiz declarationFreeBiz;

    private Logger logger = LoggerFactory.getLogger(UserServiceAction.class);

    /**
     * 微信绑定
     *
     * @param account 用户名
     * @param pwd     密码
     * @return {"msg":"提示信息","result":"绑定结果，0：绑定失败；1：绑定成功"}
     */
    @RequestMapping(value = "/bind_account")
    @ResponseBody
    public Map<String, Object> bind_account(String account, String pwd) {
        Map<String, Object> result = new HashMap<>();
        if (StringUtils.isEmpty(account) || StringUtils.isEmpty(pwd)) {
            result.put("msg", "请输入账号！");
            result.put("result", 0);
            return result;
        }
        if (StringUtils.isEmpty(pwd)) {
            result.put("msg", "请输入密码！");
            result.put("result", 0);
            return result;
        }
        return userServiceBiz.bind_account(account, pwd);
    }

    private void newUserServiceByUserAndOpenid(User user, Object sessionOpenid) {

    }


    /**
     * 判断微信账号是否已经绑定一线通账号
     *
     * @return 绑定结果，0：未绑定；1：已绑定
     */
    @RequestMapping("/has_binded")
    @ResponseBody
    public int has_binded() {
        HttpSession httpSession = HttpUtils.getSession();
        Object sessionOpenid = httpSession.getAttribute(SecurityConstants.WE_CHAT_OPEN_ID);
        Object sessionUser = httpSession.getAttribute(SecurityConstants.NEW_SESSION_USER_NAME);
        String openid = null; //微信openid
        if (sessionOpenid != null) {
            openid = sessionOpenid.toString();
        }
        User castUser = null;
        String userId = null;
        if (sessionUser != null) {
            castUser = (User) sessionUser;
            userId = castUser.getuId();
        }
        return userServiceMapper.selectBindedByUserIdAndOpenid(userId, openid) != null ? 1 : 0;
    }

    /**
     * 根据微信openID查询个人基础信息
     *
     * @return 个人基础信息
     */
    @RequestMapping("/userInfo")
    @ResponseBody
    public Map<String, Object> userInfo() {
        Map<String, Object> result = new HashMap<>();
        User user = LoginUtil.getNewLoginUser();
        if (user != null) {
            Company company = user.getCompany();
            if (company != null) {
                com.mrd.gtimpframe.entity.FundAccount fundAccount = fundAccountMapper.selectByCompanyId(company.getComId());
                BigDecimal balance = fundAccount.getBalance();

                if (balance != null) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                    DecimalFormat decimalFormat = new DecimalFormat("#,##0.00");
                    result.put("error_code", "0");
                    result.put("account", user.getuAccount());
                    result.put("refComName", company.getComName());
                    result.put("comBalance", decimalFormat.format(balance));
                    result.put("date", simpleDateFormat.format(new Date()));
                    return result;
                }
            }
        }
        result.put("error_code", "1");
        return result;
    }


    /**
     * 每月业务查询
     *
     * @param date 时间格式yyyymm
     */
    @RequestMapping("/monthDeclaList")
    @ResponseBody
    public Map<String, Object> monthDeclaList(String date) {
        return userServiceBiz.monthDeclaList(date);
    }

    /**
     * 精确日期的业务查询
     *
     * @param date 需要查询的年月日, 格式yyyy-MM-dd
     */
    @RequestMapping("/exactDay_bizInfo")
    @ResponseBody
    public Map<String, Object> exactDay_bizInfo(String date) {
        Map<String, Object> result = new HashedMap();
        try {
            User user = LoginUtil.getNewLoginUser();
            if (user != null && user.getCompany() != null) {
                List<Declaration> declarationList = declarationBiz.findByCompanyMonth(user.getCompany().getComId(), date, "yyyy-MM-dd");
                List<Map<String, Object>> contentList = this.putDeclaration(declarationList);
                result.put("error", "0");
                result.put("date", date);
                if (CollectionUtils.isEmpty(contentList)) {
                    result.put("content", "");
                } else {
                    result.put("content", contentList);
                }
                return result;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        result.put("error", "1");
        result.put("data", date);
        return result;
    }


    /**
     * 按照客户传入的柜号、报关单号进行精确查询
     *
     * @param containerNo 柜号
     * @param sno         报关单号
     */
    @RequestMapping("/exactly_bizInfo")
    @ResponseBody
    public Map<String, Object> exactly_bizInfo(@RequestParam(required = false) String containerNo, @RequestParam(required = false) String sno) {
        Map<String, Object> result = new HashMap<>();
        try {
            User user = LoginUtil.getNewLoginUser();
            if (user != null && user.getCompany() != null) {
                List<Declaration> declarationList = declarationBiz.findByCompanyContainerNoSno(user.getCompany().getComId(), containerNo, sno);
                List<DeclarationFreeDetail> declarationFreeDetails = declarationFreeDetailBiz.findAllEntity();
                declarationList = declarationFreeBiz.countFree(declarationList, declarationFreeDetails);
                List<Map<String, Object>> contentList = this.putDeclaration(declarationList);
                result.put("error", "0");
                result.put("content", contentList);
                Date date;
                if (CollectionUtils.isNotEmpty(declarationList)) {
                    Declaration d0 = declarationList.get(0);
                    date = d0.getConfirmTime();
                    if (date == null) {
                        date = d0.getMtime();
                    }
                    if (date == null) {
                        date = d0.getCtime();
                    }
                } else {
                    date = new Date();
                    result.put("content", "");
                }
                result.put("date", new SimpleDateFormat("yyyy-MM-dd").format(date));
                return result;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        result.put("error", "1");
        return result;
    }


    /**
     * 根据ID获取报关单
     *
     * @param id 报关单id
     */
    @RequestMapping("/exactly_bizInfo_from_id")
    @ResponseBody
    public Map<String, Object> exactly_bizInfo_from_id(String id) {
        Map<String, Object> result = new HashMap<>();
        try {
            User user = LoginUtil.getNewLoginUser();
            if (user != null && user.getCompany() != null) {
                Declaration declaration = declarationBiz.findEntityById(id);
                if (declaration == null) {
                    result.put("error_code", "1");
                    return result;
                }
                String state = declaration.getState();
                String state_en;
                if ("DS00".equalsIgnoreCase(state)) {
                    state = "草稿状态";
                    state_en = "craft";
                } else if ("DS03".equalsIgnoreCase(state)) {
                    //特殊状态 表示已驳回
                    state = "驳回";
                    state_en = "reject";
                } else if ("DS01".equalsIgnoreCase(state) || "DS02".equalsIgnoreCase(state) || "DS04".equalsIgnoreCase(state) || "DS06".equalsIgnoreCase(state) || "DS07".equalsIgnoreCase(state) || "DS08".equalsIgnoreCase(state)) {
                    //已提交，表示业务状态包括 包括除草稿之外的所有状态
                    //DS01, DS02, DS04，DS06，DS07，DS08
                    state = "已提交";
                    state_en = "submit";
                } else if ("DS120".equalsIgnoreCase(state) || "DS121".equalsIgnoreCase(state) || "DS122".equalsIgnoreCase(state) || "DS124".equalsIgnoreCase(state) || "DS125".equalsIgnoreCase(state) || "DS126".equalsIgnoreCase(state)) {
                    //特殊状态 查验中、查验完成、查验不通过中任意状态
                    //DS120，DS121，DS122，DS124
                    state = "查验";
                    state_en = "check";
                } else if ("DS05".equalsIgnoreCase(state)) {
                    //已完成 业务完结状态。
                    state = "完成";
                    state_en = "done";
                } else {
                    result.put("error_code", "1");
                    return result;
                }
                result.put("error_code", "0");
                result.put("id", declaration.getId());
                result.put("business_id", declaration.getBusinessId());
                result.put("container_no", declaration.getContainer_no());
                result.put("contact_no", declaration.getContract_no());
                result.put("ie_type", declaration.getDeclaration_type() == "E" ? "出口" : "进口");
                result.put("consigneeOrConsignor", declaration.getCompany_name());
                result.put("supplier", declaration.getSupCompany().getName());
                result.put("biz_state_en", state_en);
                result.put("biz_state", state);
            }
            return result;
        } catch (QueryException e) {
            e.printStackTrace();
        }
        result.put("error_code", "1");
        return result;
    }


    /**
     * 获取驳回原因列表
     */
    @RequestMapping("/gen/reject_reason_list")
    @ResponseBody
    public Map<String, Object> reject_reason_list() {
        Map<String, Object> result = new HashMap<>();
        try {
            User user = LoginUtil.getNewLoginUser();
            if (user != null && user.getCompany() != null) {
                List<Dictionary> dictionaryList = dictionaryBiz.findByDictionaryGroupCode("reject_apply_reason");
                if (CollectionUtils.isNotEmpty(dictionaryList)) {
                    List<Map<String, Object>> contentList = new ArrayList<>();
                    for (Dictionary dictionary : dictionaryList) {
                        Map<String, Object> dictMap = new HashMap<>();
                        dictMap.put("id", dictionary.getId());
                        dictMap.put("txt", dictionary.getDictionaryName());
                        contentList.add(dictMap);
                    }
                    result.put("error_code", "0");
                    result.put("content", contentList);
                    return result;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        result.put("error_code", "1");
        result.put("content", "");
        return result;
    }

    /**
     * 微信提交驳回申请
     *
     * @param business_id 业务编号
     * @param remark      备注
     */
    @RequestMapping("/apply_for_reject")
    @ResponseBody
    public Result apply_for_reject(String business_id, String remark, String rejectReasonList) {
        try {
            if (StringUtils.isEmpty(rejectReasonList)) {
                return Result.newFailInstance("请选择申请驳回原因！");
            }
            if (StringUtils.isEmpty(business_id)) {
                return Result.newFailInstance("获取报关单失败！");
            }
            String str = remark.replaceAll("\\s", "").replace("备注", "");
            if (StringUtils.isEmpty(str)) {
                remark = null;
            }
            String[] reasonArr = rejectReasonList.split(",");
            return rejectService.customerApply(business_id, reasonArr[0], remark);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("客户申请驳回出错", e);
            return Result.newFailInstance(e.getMessage());
        }
    }


    private List<Map<String, Object>> putDeclaration(List<Declaration> declarationList) {
        if (CollectionUtils.isEmpty(declarationList)) {
            return null;
        }
        List<Map<String, Object>> contentList = new ArrayList<>();
        String[] declarationIds = new String[declarationList.size()];
        int i = 0;
        for (Declaration declaration : declarationList) {
            String paymentType = declaration.getPayment_type();
            String declarationState = declaration.getState();
            String state, state_en;
            if ("DS00".equalsIgnoreCase(declarationState)) {
                state = "草稿状态";
                state_en = "craft";
            } else if ("DS03".equalsIgnoreCase(declarationState)) {
                //特殊状态 表示已驳回
                state = "驳回";
                state_en = "reject";
            } else if ("DS01".equalsIgnoreCase(declarationState) || "DS02".equalsIgnoreCase(declarationState) || "DS04".equalsIgnoreCase(declarationState) || "DS06".equalsIgnoreCase(declarationState) || "DS07".equalsIgnoreCase(declarationState) || "DS08".equalsIgnoreCase(declarationState)) {
                //已提交，表示业务状态包括 包括除草稿之外的所有状态
                //DS01, DS02, DS04，DS06，DS07，DS08
                state = "已提交";
                state_en = "submit";
            } else if ("DS120".equalsIgnoreCase(declarationState) || "DS121".equalsIgnoreCase(declarationState) || "DS122".equalsIgnoreCase(declarationState) || "DS124".equalsIgnoreCase(declarationState)) {
                //特殊状态 查验中、查验完成、查验不通过中任意状态
                //DS120，DS121，DS122，DS124
                state = "查验";
                state_en = "check";
            } else if ("DS05".equalsIgnoreCase(declarationState)) {
                //已完成 业务完结状态。
                state = "完成";
                state_en = "done";
            } else {
                continue;
            }
            declarationIds[i++] = declaration.getId();
            Map<String, Object> declarationMap = new HashMap<>();
            declarationMap.put("id", declaration.getId());
            declarationMap.put("business_id", StringUtils.isEmpty(declaration.getBusinessId()) ? "" : declaration.getBusinessId());
            declarationMap.put("container_no", StringUtils.isEmpty(declaration.getContainer_no()) ? "" : declaration.getContainer_no());
            declarationMap.put("contact_no", StringUtils.isEmpty(declaration.getContract_no()) ? "" : declaration.getContract_no());
            declarationMap.put("ie_type", "E".equals(declaration.getDeclaration_type()) ? "出口" : "进口");
            declarationMap.put("consigneeOrConsignor", declaration.getCompany_name());
            declarationMap.put("supplier", declaration.getSupCompany().getName());
            declarationMap.put("biz_state_en", state_en);
            declarationMap.put("biz_state", state);
            if ("0".equals(paymentType) && !"DS00".equalsIgnoreCase(declarationState)) {
                declarationMap.put("pay_state_code", "0");
                declarationMap.put("pay_state", "未付款");
                if (declaration.getDeclaration_free() != null) {
                    String fee = declaration.getDeclaration_free().toString();
                    declarationMap.put("fee", StringUtils.isEmpty(fee) ? " " : fee);
                }
            }
            //todo 获取查验信息

            List<DeclaCheckTracking> declaCheckTrackingList = declaration.getDeclaCheckTracking();
            if (CollectionUtils.isNotEmpty(declaCheckTrackingList)) {
                Map<String, Object> checkInfoMap = new HashMap();
                for (DeclaCheckTracking declaCheckTracking : declaCheckTrackingList) {
                    List<DeclaCheckContent> declaCheckContentList = declaCheckTracking.getDeclaCheckContentList();
                    if (CollectionUtils.isNotEmpty(declaCheckContentList)) {
                        for (DeclaCheckContent declaCheckContent : declaCheckContentList) {
                            List<DeclaCheckResult> declaCheckResultList = declaCheckContent.getDeclaCheckResultList();
                            if (CollectionUtils.isNotEmpty(declaCheckResultList)) {
                                List<Map<String, Object>> checkResultList = new ArrayList<>();
                                for (DeclaCheckResult declaCheckResult : declaCheckResultList) {
                                    Map<String, Object> checkResultMap = new HashMap();
                                    checkResultMap.put("time", declaCheckResult.getCreateTime());
                                    checkResultMap.put("state", declaCheckResult.getBizStatus());
                                    checkResultMap.put("text", declaCheckResult.getDescription());
                                    checkResultList.add(checkResultMap);
                                }
                                checkInfoMap.put("check_results", checkResultList);
                            }
                            List<Dictionary> checkItemList = declaCheckContent.getCheckItemList();
                            List<Dictionary> checkDeptList = declaCheckContent.getCheckDeptList();
                            if (CollectionUtils.isNotEmpty(checkItemList)) {
                                String check_items = "";
                                for (Dictionary checkItem : checkItemList) {
                                    check_items += checkItem.getDictionaryName() + ",";
                                }
                                check_items = check_items.substring(0, check_items.length() - 1);
                                checkInfoMap.put("check_items", check_items);
                            }
                            if (CollectionUtils.isNotEmpty(checkDeptList)) {
                                String check_depts = "";
                                for (Dictionary checkDept : checkDeptList) {
                                    check_depts += checkDept.getDictionaryName() + ",";
                                }
                                check_depts = check_depts.substring(0, check_depts.length() - 1);
                                checkInfoMap.put("check_depts", check_depts);
                            }
                        }
                    }
                }
                declarationMap.put("check_info", checkInfoMap);
            }
            contentList.add(declarationMap);
        }
        //补充驳回原因
//        List<RejectRecord> rejectRecords = rejectRecordService.selectByDidsInit(declarationIds);
        Map<String, String> propertyMap = new HashMap<>();
        StringBuffer dids = new StringBuffer();
        for (String did : declarationIds) {
            dids.append(",");
            dids.append(did);
        }
        if (StringUtils.isNotBlank(dids)) {
            dids.deleteCharAt(0);
        }
        Jqgrid jqgrid = new Jqgrid();
        jqgrid.addRule(new SearchRule("DID", SearchRuleOption.in, dids.toString()));
        propertyMap.put("whereCase", jqgrid.getWhereCase());
        List<RejectRecord> rejectRecords = rejectRecordService.selectByWhereCase(propertyMap);
        Map<String, String> rejectReasnMap = new HashMap<>();
        Map<String, Long> initTimeMap = new HashMap<>();
        for (RejectRecord rejectRecord : rejectRecords) {
            String id = rejectRecord.getDid();
            long initTime = rejectRecord.getInitiatedTime().getTime();
            if (initTimeMap.get(id) == null) {
                initTimeMap.put(id, initTime);
            } else if (initTimeMap.get(id) < initTime) {
                initTimeMap.put(id, initTime);
            }
            //只取最新的驳回原因
            if (rejectReasnMap.get(id) == null || initTimeMap.get(id) == initTime) {
                rejectReasnMap.put(id, rejectRecord.getRejectReason());
            }
        }
        for (int j = 0; j < contentList.size(); j++) {
            contentList.get(j).put("reject_reason", rejectReasnMap.get(contentList.get(j).get("id")));
        }
        return contentList;
    }
}
